/*=====================================================================
  File   :  TraceExample.cs
  Summary:  Implements a sample SMO SQL Server trace utility in C#.
  Date   :  April, 2006

  THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  PARTICULAR PURPOSE.
======================================================= */

using System;
using System.Runtime.InteropServices;
using Microsoft.SqlServer.Management.Common;
using Microsoft.SqlServer.Management.Trace;

namespace Nizm0.QOT.SQLTraceLog
{
    class Program
    {
        static void PrintUsage()
        {
            Console.WriteLine(@"Usage:\n\n\t" + @"TraceExample.exe example.tdf\n");
        }
        [STAThread]
        public static int Main(string[] args)
        {
            if (args.Length < 1)
            {
                PrintUsage();

                // failure
                return 1;
            }

            // Connect to the local default instance of SQL Server
            SqlConnectionInfo connectionInfo = new SqlConnectionInfo();
            connectionInfo.ServerName = "AIG-PC";
            connectionInfo.UseIntegratedSecurity = true;

            // Create the trace object
            TraceServer trace = new TraceServer();

            try
            {
                // Clean up trace on process exit
                StopAndCloseTraceOnExit traceCleanup = new StopAndCloseTraceOnExit(trace);

                // Start a trace using the trace definition file (passed as first command line parameters)
                Console.WriteLine("Starting trace ...\n");
                trace.InitializeAsReader(connectionInfo, args[0]);

                // Reading events
                while (trace.Read())
                {
                    Console.WriteLine("Event : " + trace["EventClass"]);
                    Console.WriteLine("SPID  : " + trace["SPID"]);
                    Console.WriteLine("Login : " + trace["SessionLoginName"]);
                    Console.WriteLine("Object: " + trace["ObjectName"]);
                    Console.WriteLine("Text  : " + trace["TextData"]);
                    Console.WriteLine();
                }
            }
            catch (SqlTraceException ex)
            {
                System.Windows.Forms.Clipboard.SetText(ex.ToString());
                Console.WriteLine(ex.ToString());
                Console.WriteLine(ex.Message);

                if (ex.InnerException != null)
                    Console.WriteLine(ex.InnerException.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

                if (ex.InnerException != null)
                    Console.WriteLine(ex.InnerException.Message);
            }
            finally
            {
                Console.ReadKey();
            }
            // success
            return 0;
        }
    }

    public class StopAndCloseTraceOnExit
    {
        private TraceServer trace;

        public StopAndCloseTraceOnExit(TraceServer trace)
        {
            this.trace = trace;
            SetConsoleCtrlHandler(new HandlerRoutine(ConsoleCtrlCheck), true);
        }

        [DllImport("Kernel32")]
        public static extern bool SetConsoleCtrlHandler(HandlerRoutine Handler, bool Add);

        public delegate bool HandlerRoutine(CtrlTypes CtrlType);

        public enum CtrlTypes 
        {
            CTRL_C_EVENT = 0,
            CTRL_BREAK_EVENT,
            CTRL_CLOSE_EVENT, 
            CTRL_LOGOFF_EVENT = 5,
            CTRL_SHUTDOWN_EVENT
        };

        private bool ConsoleCtrlCheck(CtrlTypes ctrlType) 
        {
            if (trace != null)
            {
                Console.WriteLine( "Stopping trace ...\n" );
                trace.Stop();

                Console.WriteLine( "Closing trace ...\n" );
                trace.Close();
            }

            return true;
        }
    }
}
